<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>飞机投弹爆炸效果</title>
    <script type="text/javascript" src="http://172.29.1.151:8080/libs/Cesium/1.40/Build/Cesium/Cesium.js"></script>
    <link rel="stylesheet" href="http://172.29.1.151:8080/libs/Cesium/1.40/Build/Cesium/Widgets/widgets.css"
          type="text/css"/>
    <style>
        html, body, #map3d {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
            cursor: default;
        }
    </style>
</head>
<body>
<div id="map3d"></div>
<script>
    var viewer = new Cesium.Viewer('map3d', {
        fullscreenButton: false,
        baseLayerPicker: false,
        imageryProvider: new Cesium.UrlTemplateImageryProvider({
            url: 'http://www.google.cn/maps/vt?lyrs=s@716&x={x}&y={y}&z={z}'
        })
    });

    viewer._animation.container.style.display = "none";
    viewer._timeline.container.style.display = "none";
    viewer._cesiumWidget._creditContainer.style.display = "none";

    var scene = viewer.scene;
    var camera = viewer.scene.camera;

    camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(114.064849065915, 29.994878553057447, 15.007291154869968),
        orientation: {
            heading: 5.040532816257989, // 朝向 左右旋转
            pitch: 0.15284408485189505, // 仰角 上下旋转
            roll: 6.28040490073921 // 翻转 左右摇晃
        }
    });

    /**
     * 添加一个爆炸效果
     * @param position
     */
    function addBomb(position) {

        // 爆炸模型位置
        var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position);
        var offset = Cesium.Cartesian3.add(new Cesium.Cartesian3(0.0, 0.0, 0.0), Cesium.Cartesian3.ZERO, new Cesium.Cartesian3());
        var emitterModelMatrix = Cesium.Matrix4.fromTranslation(offset, new Cesium.Matrix4());
        scene.primitives.add(new Cesium.ParticleSystem({
            image: 'fire.png',
            startColor: Cesium.Color.RED.withAlpha(0.7),
            endColor: Cesium.Color.YELLOW.withAlpha(0.3),
            startScale: 1,
            endScale: 3,
            life: 1,
            speed: 10,
            width: 20,
            height: 20,
            rate: 400,
            lifeTime: 2,
            loop: false,
            emitter: new Cesium.SphereEmitter(200),
            modelMatrix: modelMatrix,
            emitterModelMatrix: emitterModelMatrix
        }));
    }

    // 设置时间
    var start = Cesium.JulianDate.fromDate(new Date(2018, 6, 5, 8));
    var stop = Cesium.JulianDate.addSeconds(start, 120, new Cesium.JulianDate()); // 设置总时长120秒

    viewer.clock.startTime = start.clone();
    viewer.clock.stopTime = stop.clone();
    viewer.clock.currentTime = start.clone();
    viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end
    viewer.clock.multiplier = 5; // 10倍速率播放

    viewer.timeline.zoomTo(start, stop);

    function computeAirPlaneTrack() {
        var property = new Cesium.SampledPositionProperty();
        // 飞机路线
        property.addSample(Cesium.JulianDate.addSeconds(start, 0, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.0, 30.0, 1000));
        property.addSample(Cesium.JulianDate.addSeconds(start, 10, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.01, 30.0, 850));
        property.addSample(Cesium.JulianDate.addSeconds(start, 20, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.02, 30.0, 700));
        property.addSample(Cesium.JulianDate.addSeconds(start, 30, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.03, 30.0, 500));
        property.addSample(Cesium.JulianDate.addSeconds(start, 40, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.04, 30.0, 400));
        property.addSample(Cesium.JulianDate.addSeconds(start, 50, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.05, 30.0, 450));
        property.addSample(Cesium.JulianDate.addSeconds(start, 60, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.06, 30.0, 500));
        property.addSample(Cesium.JulianDate.addSeconds(start, 70, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.07, 30.0, 600));
        property.addSample(Cesium.JulianDate.addSeconds(start, 80, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.08, 30.0, 700));
        property.addSample(Cesium.JulianDate.addSeconds(start, 90, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.09, 30.0, 800));
        property.addSample(Cesium.JulianDate.addSeconds(start, 100, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.1, 30.0, 900));
        return property;
    }

    function computeBomb1Track() {
        var property = new Cesium.SampledPositionProperty();
        // 炸弹路线
        property.addSample(Cesium.JulianDate.addSeconds(start, 20, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.02, 30.0, 700));
        property.addSample(Cesium.JulianDate.addSeconds(start, 25, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.025, 30.0, 500));
        property.addSample(Cesium.JulianDate.addSeconds(start, 30, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.03, 30.0, 0));
        return property;
    }

    var bomb1start = Cesium.JulianDate.addSeconds(start, 20, new Cesium.JulianDate());
    var bomb1stop = Cesium.JulianDate.addSeconds(start, 30, new Cesium.JulianDate());

    function computeBomb2Track() {
        var property = new Cesium.SampledPositionProperty();
        // 炸弹路线
        property.addSample(Cesium.JulianDate.addSeconds(start, 30, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.03, 30.0, 500));
        property.addSample(Cesium.JulianDate.addSeconds(start, 35, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.035, 30.0, 300));
        property.addSample(Cesium.JulianDate.addSeconds(start, 40, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.04, 30.0, 0));
        return property;
    }

    var bomb2start = Cesium.JulianDate.addSeconds(start, 30, new Cesium.JulianDate());
    var bomb2stop = Cesium.JulianDate.addSeconds(start, 40, new Cesium.JulianDate());

    function computeBomb3Track() {
        var property = new Cesium.SampledPositionProperty();
        // 炸弹路线
        property.addSample(Cesium.JulianDate.addSeconds(start, 40, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.04, 30.0, 400));
        property.addSample(Cesium.JulianDate.addSeconds(start, 45, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.045, 30.0, 280));
        property.addSample(Cesium.JulianDate.addSeconds(start, 50, new Cesium.JulianDate()), Cesium.Cartesian3.fromDegrees(114.05, 30.0, 0));
        return property;
    }

    var bomb3start = Cesium.JulianDate.addSeconds(start, 40, new Cesium.JulianDate());
    var bomb3stop = Cesium.JulianDate.addSeconds(start, 50, new Cesium.JulianDate());

    var airPosition = computeAirPlaneTrack();
    var bomb1Position = computeBomb1Track();
    var bomb2Position = computeBomb2Track();
    var bomb3Position = computeBomb3Track();

    var airEntity = viewer.entities.add({
        availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
            start: start,
            stop: stop
        })]),
        position: airPosition,
        orientation: new Cesium.VelocityOrientationProperty(airPosition),
        model: {
            uri: 'Cesium_Air.gltf',
            minimumPixelSize: 64
        },
        // path: {
        //     resolution: 1,
        //     material: new Cesium.PolylineGlowMaterialProperty({
        //         glowPower: 0.2,
        //         color: Cesium.Color.YELLOW
        //     }),
        //     width: 10
        // }
    });

    var bomb1Entity = viewer.entities.add({
        availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
            start: bomb1start,
            stop: bomb1stop
        })]),
        position: bomb1Position,
        orientation: new Cesium.VelocityOrientationProperty(bomb1Position),
        model: {
            uri: 'bomb.gltf',
            minimumPixelSize: 24,
            color: Cesium.Color.GREY.withAlpha(0.8)
        },
        // path: {
        //     resolution: 1,
        //     material: new Cesium.PolylineGlowMaterialProperty({
        //         glowPower: 0.2,
        //         color: Cesium.Color.YELLOW
        //     }),
        //     width: 10
        // }
    });

    var bomb2Entity = viewer.entities.add({
        availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
            start: bomb2start,
            stop: bomb2stop
        })]),
        position: bomb2Position,
        orientation: new Cesium.VelocityOrientationProperty(bomb2Position),
        model: {
            uri: 'bomb.gltf',
            minimumPixelSize: 24,
            color: Cesium.Color.GREY.withAlpha(0.8)
        },
        // path: {
        //     resolution: 1,
        //     material: new Cesium.PolylineGlowMaterialProperty({
        //         glowPower: 0.2,
        //         color: Cesium.Color.YELLOW
        //     }),
        //     width: 10
        // }
    });

    var bomb3Entity = viewer.entities.add({
        availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
            start: bomb3start,
            stop: bomb3stop
        })]),
        position: bomb3Position,
        orientation: new Cesium.VelocityOrientationProperty(bomb3Position),
        model: {
            uri: 'bomb.gltf',
            minimumPixelSize: 24,
            color: Cesium.Color.GREY.withAlpha(0.8)
        },
        // path: {
        //     resolution: 1,
        //     material: new Cesium.PolylineGlowMaterialProperty({
        //         glowPower: 0.2,
        //         color: Cesium.Color.YELLOW
        //     }),
        //     width: 10
        // }
    });

    airEntity.position.setInterpolationOptions({
        interpolationDegree: 5,
        interpolationAlgorithm: Cesium.LagrangePolynomialApproximation
    });

    bomb1Entity.position.setInterpolationOptions({
        interpolationDegree: 10,
        interpolationAlgorithm: Cesium.LagrangePolynomialApproximation
    });

    bomb2Entity.position.setInterpolationOptions({
        interpolationDegree: 10,
        interpolationAlgorithm: Cesium.LagrangePolynomialApproximation
    });

    bomb3Entity.position.setInterpolationOptions({
        interpolationDegree: 10,
        interpolationAlgorithm: Cesium.LagrangePolynomialApproximation
    });

    var flag1 = true;
    var flag2 = true;
    var flag3 = true;
    scene.preRender.addEventListener(function (scene, time) {
        if (flag1 && Cesium.JulianDate.greaterThanOrEquals(viewer.timeline._clock.currentTime, Cesium.JulianDate.addSeconds(start, 30, new Cesium.JulianDate()))) {
            var position = Cesium.Cartesian3.fromDegrees(114.03, 30.0, 1);
            addBomb(position);
            flag1 = false;
        } else if (flag2 && Cesium.JulianDate.greaterThanOrEquals(viewer.timeline._clock.currentTime, Cesium.JulianDate.addSeconds(start, 40, new Cesium.JulianDate()))) {
            var position = Cesium.Cartesian3.fromDegrees(114.04, 30.0, 1);
            addBomb(position);
            flag2 = false;
        } else if (flag3 && Cesium.JulianDate.greaterThanOrEquals(viewer.timeline._clock.currentTime, Cesium.JulianDate.addSeconds(start, 50, new Cesium.JulianDate()))) {
            var position = Cesium.Cartesian3.fromDegrees(114.05, 30.0, 1);
            addBomb(position);
            flag3 = false;
        } else if (Cesium.JulianDate.lessThanOrEquals(viewer.timeline._clock.currentTime, Cesium.JulianDate.addSeconds(start, 10, new Cesium.JulianDate()))) {
            flag1 = true;
            flag2 = true;
            flag3 = true;
        }
    });

    /**
     * 获取当前视角
     */
    function getCamera() {
        var heading = scene.camera.heading;
        var pitch = scene.camera.pitch;
        var roll = scene.camera.roll;
        var position = scene.camera.position;
        var ellipsoid = scene.globe.ellipsoid;
        var cartographic = ellipsoid.cartesianToCartographic(position);
        var lat = Cesium.Math.toDegrees(cartographic.latitude);
        var lon = Cesium.Math.toDegrees(cartographic.longitude);
        var height = cartographic.height;
        console.log(heading);
        console.log(pitch);
        console.log(roll);
        console.log(lon);
        console.log(lat);
        console.log(height);
    }

</script>
</body>
</html>